package com.jhws.core.spring.TimerTask;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.ServletContext;

import com.jhws.sys.params.bo.SysParam;
import com.jhws.sys.params.bo.SysParamConstant;
import com.jhws.sys.params.service.SysParamService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;

import com.jhws.business.comm.bo.TblBuildingDimBo;
import com.jhws.business.comm.bo.TblCommDimBo;
import com.jhws.business.owner.bo.TblOwnerDimBo;
import com.jhws.sys.user.bo.TblUserDimBo;
import com.jhws.util.GetId;
import com.jhws.common.PropertiesReader;
import com.jhws.util.net.JhHttpClient;
import com.jhws.business.comm.service.ITblBuildingDimService;
import com.jhws.business.comm.service.ITblCommDimService;
import com.jhws.business.owner.service.ITblOwnerDimService;
import com.jhws.sys.user.service.ITblUserDimService;
import com.jhws.util.DateUtil;
import com.jhws.util.file.FileUtil;
import com.jhws.util.LogHelper;
import com.jhws.util.ZipUtil;
import com.jhws.util.jsonUtil;

/**
 * @Create : 2016-9-26 下午5:50:41
 * @author : Alex Tan
 * @Comment : 只给本地服务器使用， 每天凌晨12点到第二天2点之间随机执行，同步公网本小区数据到本地备份
 */
//@Component
public class updateLocalServerTimerTask {
	
	private String serverUrl = "http://app.jhws.top:8081";
			
	@Resource
	ITblUserDimService ITblUserDimService;
	@Resource
	ITblCommDimService ITblCommDimService;
	@Resource
	ITblOwnerDimService ITblOwnerDimService;
	@Resource
	ITblBuildingDimService IBuildingService;
	@Resource
	SysParamService IParamService;

	private TblCommDimBo commDimBo = null;

	private Map<String,String> getLocalSrvHeaders() throws Exception{
		if(commDimBo == null)
			return null;
		Map<String,String> map = new HashMap<>();
		String commPassword =  commDimBo.getCommPassword();
		map.put("commPassword",commPassword);
		return map;
	}
	/**
	 * @Comment: spring task, 自动运行，由app.properties文件中的isLanMode属性控制是否执行
	 * @Param:
	 */
	@Scheduled(cron = "0 0 1 * * *")
	void updateLocalServerDataTask(){
		/* 局域网服务端才启动 */
		if(PropertiesReader.getProperty("isLanMode").equals("false"))
			return;
		
		int executeUpdateLocalServerInSeconds = 7200;
		ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
		int delay = (int) (Math.random()*executeUpdateLocalServerInSeconds);
		
		scheduler.schedule(
			new Runnable() {
				public void run() {
					try {
						LogHelper.getLogger().debug("execute updateLocalServerDataTask at "+DateUtil.getTimeNowFmtSec());
						UpdateVisitorPhoto();
						updateOwner();
						updateManagerAccount();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}, delay, TimeUnit.SECONDS);
		
	}
	
	/* 获取局域网服务器的小区号，前提是局域网服务端只能存在唯一的小区，记得清空其他数据 */
	TblCommDimBo getLocalSrvComm() throws Exception{
		List<TblCommDimBo> list = ITblCommDimService.findTblCommDimByWhere("");
		if(list.size() == 0)
			return null;
		else
			return list.get(0);
	}
	

	/**
	 * @Comment: 执行访客图片同步动作
	 * 		1. 判断今天是否已经同步(本地目录搜索当天文件是否存在),如果已经同步，则停止，否则同步
	 * 		2. 同步完今天的继续这个动作判断上一天是否同步，假如没有则同步
	 * 		3. 一直到服务端无法获取到当天的文件为止
	 * @Param:
	 */
	void UpdateVisitorPhoto() throws Exception{
		ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
        String commCode = commDimBo.getCommCode();
        if(commCode == null){
			LogHelper.getLogger().debug("commCode == null");
			return;
		}
        String outdoorDir = servletContext.getRealPath("/")+"visitors/"+commCode+"/outdoor/";
        String date = DateUtil.getTimeYestodayFmtDay();
        while(true){
        	if(FileUtil.exsit(outdoorDir+date)){
        		LogHelper.getLogger().debug(date+" exist");
        		break;
        	}
        	byte [] buffer = new byte[1024*1024];
			JhHttpClient.download(serverUrl + servletContext.getContextPath() + "/api/LocalSrv/downLoadVisitors?commCode="+commCode+"&date="+date,
					servletContext.getRealPath("/")+"visitor.zip",buffer ,getLocalSrvHeaders());
			/* 文件小于100字节判断为压缩包为空，下载失败 */
			if(FileUtil.getFileSpace(servletContext.getRealPath("/")+"visitor.zip") < 100){
				LogHelper.getLogger().debug(date+" cannot download!");
				break;
			}

			ZipUtil.unZipFile(servletContext.getRealPath("/")+"visitor.zip", servletContext.getRealPath("/")+"/visitors/");
			date = DateUtil.getTheDayBefore(date);
			FileUtil.deleteFile(servletContext.getRealPath("/")+"visitor.zip");
        }
	}

	void updateOwner() throws Exception{
		Long timeStamp = (long) -1;
		SysParam param = IParamService.getParam( "timeStampLocalSrvOwner");
		if(param != null) {
			timeStamp = Long.valueOf(param.getValue());
		}
		ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
		JhHttpClient hp = new JhHttpClient();
		String str = hp.get(serverUrl + servletContext.getContextPath() + "/api/LocalSrv/updateOwner?commCode="+commDimBo.getCommCode()+"&timeStamp="+timeStamp,getLocalSrvHeaders());
		LogHelper.getLogger().debug("got data:"+str);
		if((Integer)jsonUtil.getKeyFromJsonObject(str,"ret_code") == -1){
			LogHelper.getLogger().debug("error "+(String)jsonUtil.getKeyFromJsonObject(str,"data"));
			return;
		}
		List<TblOwnerDimBo> retList = jsonUtil.getBeansFromJsonDataObject(str, "list",TblOwnerDimBo.class);
		for(TblOwnerDimBo bo : retList){
			ITblOwnerDimService.save(bo);
		}

		Long tStamp = (Long)jsonUtil.getKeyFromJsonDataObject(str, "timeStamp");
		if(tStamp == -1)
			return;

		if(param == null ){
			param = new SysParam();
			param.setName("timeStampLocalSrvOwner");
		}

		param.setValue(tStamp.toString());
		param.setParent(SysParamConstant.PARAM_TYPE_LOCAL_SERVER);
		IParamService.save(param);
	}

	void updateManagerAccount() throws Exception {
		ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
		JhHttpClient hp = new JhHttpClient();
		String str = hp.get(serverUrl + servletContext.getContextPath() + "/api/LocalSrv/updateManagerAccount?commCode="+commDimBo.getCommCode(),getLocalSrvHeaders());
		LogHelper.getLogger().debug("got data:"+str);
		if((Integer)jsonUtil.getKeyFromJsonObject(str,"ret_code") == -1){
			LogHelper.getLogger().debug("data error");
			return;
		}
		List<TblUserDimBo> retList = jsonUtil.getBeansFromJsonObjectStr(str,"data",TblUserDimBo.class);
		for(TblUserDimBo bo : retList){
			ITblUserDimService.save(bo);
		}
	}
	
	@PostConstruct
	void init() throws Exception {
		/* 局域网服务端才启动 */
		if(PropertiesReader.getProperty("isLanMode").equals("false"))
			return;

		commDimBo = getLocalSrvComm();
		ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
		int delay = 30;
		
		scheduler.schedule(
			new Runnable() {
				public void run() {
					try {
						LogHelper.getLogger().debug("execute init at : "+DateUtil.getTimeNowFmtSec());

						//UpdateVisitorPhoto();
						updateOwner();
						updateManagerAccount();

						String LocalComm = commDimBo.getCommCode();
						Long timeStamp = (long) -1;
						SysParam param = IParamService.getParam("timeStampLocalSrvBuilding");
						if(param != null ) {
							timeStamp = Long.valueOf(param.getValue());
						}
						
						int count = IBuildingService.getCountByComm(LocalComm);
						if(count == 0)
							timeStamp = (long)-1;
						
						ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
						JhHttpClient hp = new JhHttpClient();
						String str = hp.get(serverUrl +  "/api/LocalSrv/updateBuildings?commCode="+LocalComm+"&timeStamp="+timeStamp,getLocalSrvHeaders());
						if((Integer)jsonUtil.getKeyFromJsonObject(str,"ret_code") == -1){
							LogHelper.getLogger().debug("data error");
							return;
						}
						LogHelper.getLogger().debug("get data "+str);
						List<TblBuildingDimBo> retList = jsonUtil.getBeansFromJsonDataObject(str, "list",TblBuildingDimBo.class);
						for(TblBuildingDimBo bo : retList){
							bo.setBuildingCode(null);
							IBuildingService.save(bo);
						}
						
						Integer tStamp = jsonUtil.getKeyFromJsonDataObject(str, "timeStamp");
						if(tStamp == -1)
							return;

						if(param == null ){
							param = new SysParam();
							param.setName("timeStampLocalSrvBuilding");
						}

						param.setValue(tStamp.toString());
						param.setParent(SysParamConstant.PARAM_TYPE_LOCAL_SERVER);
						IParamService.save(param);


					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}, delay, TimeUnit.SECONDS);
	}
}
